package gob.cgr.web.sgrh.error;

import java.util.Iterator;
import java.util.Map;

import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
import javax.validation.ValidationException;

public class CustomExceptionHandler extends ExceptionHandlerWrapper {

	private ExceptionHandler parent;

	public CustomExceptionHandler(ExceptionHandler parent) {
		this.parent = parent;
	}

	@Override
	public ExceptionHandler getWrapped() {
		return this.parent;
	}

	@Override
	public void handle() throws FacesException {
		for (Iterator<ExceptionQueuedEvent> it = getUnhandledExceptionQueuedEvents()
				.iterator(); it.hasNext();) {
			ExceptionQueuedEvent event = it.next();
			System.out.println("Iterating over ExceptionQueuedEvents. Current:"
					+ event.toString());
			ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event
					.getSource();
			Throwable t = context.getException();
			
			if (t instanceof ViewExpiredException) {
				ViewExpiredException vee = (ViewExpiredException) t;
				FacesContext fc = FacesContext.getCurrentInstance();

				NavigationHandler nav = fc.getApplication()
						.getNavigationHandler();
				try {
					// Push some useful stuff to the flash scope for
					// use in the page
					fc.getExternalContext().getFlash()
							.put("expiredViewId", vee.getViewId());
					System.out
							.println("Error, pero se ha manejado la excepcion viewexpiredException retornando a index.jsp");
					nav.handleNavigation(fc, null, "/index.jsp");//.jsf?faces-redirect=true");
					fc.renderResponse();

				} finally {

					it.remove();
				}
			}
			
			if (t instanceof javax.faces.component.UpdateModelException) {
				// Verifico si la excepcion raiz es de validation exception (ej.
				// desde la entidad)
				Throwable tr = t;
				while (tr.getCause() != null) {
					tr = tr.getCause();
					}

				if (tr instanceof javax.validation.ValidationException) {
					FacesContext fc = FacesContext.getCurrentInstance();
					final Map<String, Object> requestMap = fc
							.getExternalContext().getRequestMap();
					try {
						requestMap.put("errorMsg", tr.getMessage());
						
						fc.addMessage(null,
								new FacesMessage(FacesMessage.SEVERITY_WARN,
										"Alerta", tr.getMessage()));
						System.out.println("agregado el mensaje");
						fc.renderResponse();

					} catch (Exception e) {
						// TODO: handle exception
						System.out
								.println("error manejando exepcion tipo updateModel - validationException"
										+ e.getMessage());
					} finally {
						it.remove();
					}
				}
			}

			/*
			 * 
			 * Throwable t = it.next().getContext().getException(); while ((t
			 * instanceof FacesException || t instanceof EJBException || t
			 * instanceof ELException) && t.getCause() != null) { t =
			 * t.getCause(); } if (t instanceof FileNotFoundException //|| t
			 * instanceof HandledException || t instanceof ViewExpiredException)
			 * { final FacesContext facesContext =
			 * FacesContext.getCurrentInstance(); final ExternalContext
			 * externalContext = facesContext.getExternalContext(); final
			 * Map<String, Object> requestMap = externalContext.getRequestMap();
			 * try { //LOG.info("{}: {}", t.getClass().getSimpleName(),
			 * t.getMessage()); String message; if (t instanceof
			 * ViewExpiredException) { final String viewId =
			 * ((ViewExpiredException) t).getViewId(); message =
			 * "View is expired. <a href='/ifos"+ viewId + "'>Back</a>"; } else
			 * { message = t.getMessage(); // beware, don't leak internal info!
			 * } requestMap.put("errorMsg", message); try {
			 * externalContext.dispatch("/error.jsp"); } catch (final
			 * IOException e) { //LOG.error("Error view '/error.jsp' unknown!",
			 * e); } facesContext.responseComplete(); } finally { it.remove(); }
			 * } } getWrapped().handle(); }
			 */

		}
		// At this point, the queue will not contain any ViewExpiredEvents.
		// Therefore, let the parent handle them.
		// System.out.println("HANDLE TO PARENT");
		getWrapped().handle();
	}

}
